{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "58aa3d75-5a9b-43d8-8bea-f391319e5710",
   "metadata": {},
   "source": [
    "Chapter 03\n",
    "\n",
    "# 矩阵乘法第二视角\n",
    "《线性代数》 | 鸢尾花书：数学不难"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e280b673-1a06-4913-ba7b-2f39f60cd7e1",
   "metadata": {},
   "source": [
    "这段代码主要涉及矩阵运算，包括矩阵转置、矩阵乘法，以及对矩阵乘法的逐元素计算。接下来，从数学角度详细描述代码的计算过程，并结合数学公式进行解析。\n",
    "\n",
    "---\n",
    "\n",
    "### **1. 定义矩阵**\n",
    "首先，定义一个 $2 \\times 3$ 的矩阵 $A$：\n",
    "$$\n",
    "A = \\begin{bmatrix} 1 & 2 & 3 \\\\ 4 & 5 & 6 \\end{bmatrix}\n",
    "$$\n",
    "然后，计算 $A$ 的转置矩阵 $B = A^T$，得到：\n",
    "$$\n",
    "B = \\begin{bmatrix} 1 & 4 \\\\ 2 & 5 \\\\ 3 & 6 \\end{bmatrix}\n",
    "$$\n",
    "\n",
    "---\n",
    "\n",
    "### **2. 计算矩阵乘法 $C = A B$**\n",
    "矩阵 $C$ 由 $A$ 和 $B$ 相乘得到，即：\n",
    "$$\n",
    "C = A B = \\begin{bmatrix} 1 & 2 & 3 \\\\ 4 & 5 & 6 \\end{bmatrix} \\times \\begin{bmatrix} 1 & 4 \\\\ 2 & 5 \\\\ 3 & 6 \\end{bmatrix}\n",
    "$$\n",
    "按照矩阵乘法的定义：\n",
    "$$\n",
    "C_{ij} = \\sum_{k=1}^{3} A_{ik} B_{kj}\n",
    "$$\n",
    "计算每个元素：\n",
    "$$\n",
    "C_{11} = 1 \\times 1 + 2 \\times 2 + 3 \\times 3 = 14, \\quad C_{12} = 1 \\times 4 + 2 \\times 5 + 3 \\times 6 = 32\n",
    "$$\n",
    "$$\n",
    "C_{21} = 4 \\times 1 + 5 \\times 2 + 6 \\times 3 = 32, \\quad C_{22} = 4 \\times 4 + 5 \\times 5 + 6 \\times 6 = 77\n",
    "$$\n",
    "最终得到：\n",
    "$$\n",
    "C = \\begin{bmatrix} 14 & 32 \\\\ 32 & 77 \\end{bmatrix}\n",
    "$$\n",
    "\n",
    "---\n",
    "\n",
    "### **3. 按列计算 $C$**\n",
    "代码中逐列计算 $C$，即：\n",
    "$$\n",
    "C_1 = A_{[:, 0]} B_{[0, :]} = \\begin{bmatrix} 1 \\\\ 4 \\end{bmatrix} \\times \\begin{bmatrix} 1 & 4 \\end{bmatrix} = \\begin{bmatrix} 1 & 4 \\\\ 4 & 16 \\end{bmatrix}\n",
    "$$\n",
    "$$\n",
    "C_2 = A_{[:, 1]} B_{[1, :]} = \\begin{bmatrix} 2 \\\\ 5 \\end{bmatrix} \\times \\begin{bmatrix} 2 & 5 \\end{bmatrix} = \\begin{bmatrix} 4 & 10 \\\\ 10 & 25 \\end{bmatrix}\n",
    "$$\n",
    "$$\n",
    "C_3 = A_{[:, 2]} B_{[2, :]} = \\begin{bmatrix} 3 \\\\ 6 \\end{bmatrix} \\times \\begin{bmatrix} 3 & 6 \\end{bmatrix} = \\begin{bmatrix} 9 & 18 \\\\ 18 & 36 \\end{bmatrix}\n",
    "$$\n",
    "叠加得到：\n",
    "$$\n",
    "C_1 + C_2 + C_3 = C\n",
    "$$\n",
    "\n",
    "---\n",
    "\n",
    "### **4. 逐元素计算 $C$**\n",
    "代码使用一个循环计算 $C$：\n",
    "$$\n",
    "C_{\\text{manual}} = \\sum_{k=1}^{3} C_k\n",
    "$$\n",
    "这是对矩阵乘法的分解计算方法，验证了矩阵乘法的正确性。\n",
    "\n",
    "---\n",
    "\n",
    "### **5. 计算 $D = B A$**\n",
    "接下来计算矩阵 $D$：\n",
    "$$\n",
    "D = B A = \\begin{bmatrix} 1 & 4 \\\\ 2 & 5 \\\\ 3 & 6 \\end{bmatrix} \\times \\begin{bmatrix} 1 & 2 & 3 \\\\ 4 & 5 & 6 \\end{bmatrix}\n",
    "$$\n",
    "同样按照矩阵乘法的定义：\n",
    "$$\n",
    "D_{ij} = \\sum_{k=1}^{2} B_{ik} A_{kj}\n",
    "$$\n",
    "计算各元素：\n",
    "$$\n",
    "D_{11} = 1 \\times 1 + 4 \\times 4 = 17, \\quad D_{12} = 1 \\times 2 + 4 \\times 5 = 22, \\quad D_{13} = 1 \\times 3 + 4 \\times 6 = 27\n",
    "$$\n",
    "$$\n",
    "D_{21} = 2 \\times 1 + 5 \\times 4 = 22, \\quad D_{22} = 2 \\times 2 + 5 \\times 5 = 29, \\quad D_{23} = 2 \\times 3 + 5 \\times 6 = 36\n",
    "$$\n",
    "$$\n",
    "D_{31} = 3 \\times 1 + 6 \\times 4 = 27, \\quad D_{32} = 3 \\times 2 + 6 \\times 5 = 36, \\quad D_{33} = 3 \\times 3 + 6 \\times 6 = 45\n",
    "$$\n",
    "最终得到：\n",
    "$$\n",
    "D = \\begin{bmatrix} 17 & 22 & 27 \\\\ 22 & 29 & 36 \\\\ 27 & 36 & 45 \\end{bmatrix}\n",
    "$$\n",
    "\n",
    "---\n",
    "\n",
    "### **6. 按列计算 $D$**\n",
    "代码逐列计算 $D$：\n",
    "$$\n",
    "D_1 = B_{[:, 0]} A_{[0, :]} = \\begin{bmatrix} 1 \\\\ 2 \\\\ 3 \\end{bmatrix} \\times \\begin{bmatrix} 1 & 2 & 3 \\end{bmatrix} = \\begin{bmatrix} 1 & 2 & 3 \\\\ 2 & 4 & 6 \\\\ 3 & 6 & 9 \\end{bmatrix}\n",
    "$$\n",
    "$$\n",
    "D_2 = B_{[:, 1]} A_{[1, :]} = \\begin{bmatrix} 4 \\\\ 5 \\\\ 6 \\end{bmatrix} \\times \\begin{bmatrix} 4 & 5 & 6 \\end{bmatrix} = \\begin{bmatrix} 16 & 20 & 24 \\\\ 20 & 25 & 30 \\\\ 24 & 30 & 36 \\end{bmatrix}\n",
    "$$\n",
    "$$\n",
    "D_1 + D_2 = D\n",
    "$$\n",
    "\n",
    "---\n",
    "\n",
    "### **7. 逐元素计算 $D$**\n",
    "代码使用循环计算 $D$：\n",
    "$$\n",
    "D_{\\text{manual}} = \\sum_{k=1}^{2} D_k\n",
    "$$\n",
    "这个方法验证了矩阵乘法的正确性，并通过逐步相加的方式计算出最终的矩阵乘积。\n",
    "\n",
    "---\n",
    "\n",
    "### **总结**\n",
    "这段代码的核心内容是：\n",
    "1. 计算 $A$ 的转置 $B$，然后计算 $A B$ 和 $B A$。\n",
    "2. 通过列向量的方式分解矩阵乘法，将矩阵乘法表示为多个外积的叠加。\n",
    "3. 使用循环实现矩阵乘法的分解计算，进一步验证矩阵乘法的正确性。\n",
    "\n",
    "这种方法有助于理解矩阵乘法的本质，即矩阵乘法可以看作多个列向量（或行向量）的外积之和。这种思路对于深入理解矩阵运算、优化计算、以及理解机器学习中的矩阵操作非常重要。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "154068f3-d35a-48f9-a120-e6c5c276c659",
   "metadata": {},
   "source": [
    "## 初始化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "06bbbb2f-a859-41e4-8073-f154fe95ee4e",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7ba209c7-e728-44b6-b6ac-a04f59f37e37",
   "metadata": {},
   "source": [
    "## 定义矩阵 A"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "99542863-0c1d-4fac-a6ea-1441d2085d97",
   "metadata": {},
   "outputs": [],
   "source": [
    "A = np.array([[1, 2, 3], \n",
    "              [4, 5, 6]])"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7e0bf4ae-7bf6-4963-b49f-e18db500d223",
   "metadata": {},
   "source": [
    "## 计算矩阵 B，即 A 的转置"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "30eff698-6fec-4b5d-ab1c-cd5e02b5e0e8",
   "metadata": {},
   "outputs": [],
   "source": [
    "B = A.T"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e354c300-c5aa-48c1-8624-637c1da961fc",
   "metadata": {},
   "source": [
    "## 计算矩阵乘法 C = A @ B"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "c444762e-ef35-4a4f-83ad-a217be49be42",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[14, 32],\n",
       "       [32, 77]])"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "C = A @ B\n",
    "C"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8c29675d-e59a-4874-bf56-b164496d14a4",
   "metadata": {},
   "source": [
    "## $C_1$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "4d54dc5d-5b59-4396-ae7f-b9a7e1482d03",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1],\n",
       "       [4]])"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A[:,[0]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "5e241bcc-48c4-499c-840d-4263605aea08",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 4]])"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "B[[0],:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "c5bdb5d4-4085-4542-9c21-13d2375f769f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 1,  4],\n",
       "       [ 4, 16]])"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "C_1 = A[:,[0]] @ B[[0],:]\n",
    "C_1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b7bd490b-ccc1-4763-bd45-7809f96d493a",
   "metadata": {},
   "source": [
    "## $C_2$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "78b6b13a-f21b-4ac9-b3d4-0decdd035c65",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[2],\n",
       "       [5]])"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A[:,[1]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "b664af24-2577-4d08-9f4a-83df68883ea0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[2, 5]])"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "B[[1],:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "ddb2740c-f23d-46e4-ad6d-d2b1a102cb32",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 4, 10],\n",
       "       [10, 25]])"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "C_2 = A[:,[1]] @ B[[1],:]\n",
    "C_2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c239d413-3f75-44f0-a5e4-702928fae10d",
   "metadata": {},
   "source": [
    "## $C_3$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "124de481-083f-4a59-99d7-73f5dceb5c1e",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[3],\n",
       "       [6]])"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A[:,[2]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "8d82d353-4b23-45ff-85a8-6fd4f5721b99",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[3, 6]])"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "B[[2],:]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "7dec6970-2a40-4ae9-aa99-c8ccd7b47209",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ 9, 18],\n",
       "       [18, 36]])"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "C_3 = A[:,[2]] @ B[[2],:]\n",
    "C_3"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5b99c40e-97a6-4514-92a1-2e50efb0f56b",
   "metadata": {},
   "source": [
    "## 叠加"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "dc1b7a7f-525b-4d22-975d-6e13afa71589",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[14, 32],\n",
       "       [32, 77]])"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "C_1 + C_2 + C_3"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "05380685-dce2-4ee4-a6bb-e0ee19cda666",
   "metadata": {},
   "source": [
    "## 逐元素计算 C 的每个元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "4d87aa08-c829-4034-9615-6a5f6f67edc1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[14, 32],\n",
       "       [32, 77]])"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "rows, cols = A.shape\n",
    "C_manual = np.zeros_like(C)\n",
    "\n",
    "for k in range(cols):\n",
    "    C_k = A[:,[k]] @ B [[k],:]\n",
    "    C_manual = C_manual + C_k\n",
    "\n",
    "C_manual"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "72f74467-3c52-44c9-bcdf-0e37cf5d3e10",
   "metadata": {},
   "source": [
    "## 计算B @ A"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "b8939b70-2dda-4933-8111-8d57a92495da",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[17, 22, 27],\n",
       "       [22, 29, 36],\n",
       "       [27, 36, 45]])"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "D = B @ A\n",
    "D"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "239a15a6-1422-47b7-ba4a-8f5d9c2c6cc8",
   "metadata": {},
   "source": [
    "## $D_k$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "f6a3832e-fa7c-4eaa-9c01-5120820c3fa4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[1, 2, 3],\n",
       "       [2, 4, 6],\n",
       "       [3, 6, 9]])"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "D_1 = B[:,[0]] @ A[[0],:]\n",
    "D_1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "672dd610-8e7e-4ab8-b7d0-aabd6d31ef7c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[16, 20, 24],\n",
       "       [20, 25, 30],\n",
       "       [24, 30, 36]])"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "D_2 = B[:,[1]] @ A[[1],:]\n",
    "D_2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "96c1870f-d918-49fe-9203-c29ea8ef25cc",
   "metadata": {},
   "source": [
    "## 叠加"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "9e7fa83e-12e0-4216-a514-c5b2dc685ac3",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[17, 22, 27],\n",
       "       [22, 29, 36],\n",
       "       [27, 36, 45]])"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "D_1 + D_2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "53f24b72-cfa9-441c-a0a5-881650052883",
   "metadata": {},
   "source": [
    "## 逐元素计算 D 的每个元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "6e252f85-4c0a-4cbb-baa6-dc7b6b980b22",
   "metadata": {},
   "outputs": [],
   "source": [
    "rows, cols = B.shape\n",
    "D_manual = np.zeros_like(D)\n",
    "\n",
    "for k in range(cols):\n",
    "    D_k = B[:,[k]] @ A[[k],:]\n",
    "    D_manual = D_manual + D_k"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "627233e1-2db2-4d82-9ad2-fe6ca94abd21",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[17, 22, 27],\n",
       "       [22, 29, 36],\n",
       "       [27, 36, 45]])"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "D_manual"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3431bd40-05cd-4fc3-9702-c991747834ee",
   "metadata": {},
   "source": [
    "作者\t**生姜DrGinger**  \n",
    "脚本\t**生姜DrGinger**  \n",
    "视频\t**崔崔CuiCui**  \n",
    "开源资源\t[**GitHub**](https://github.com/Visualize-ML)  \n",
    "平台\t[**油管**](https://www.youtube.com/@DrGinger_Jiang)\t\t\n",
    "\t\t[**iris小课堂**](https://space.bilibili.com/3546865719052873)\t\t\n",
    "\t\t[**生姜DrGinger**](https://space.bilibili.com/513194466)  "
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:base] *",
   "language": "python",
   "name": "conda-base-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
